package com.yc.cloud.openai.portal.dao.impl;

import cn.hutool.core.codec.Base64;
import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.audio.AudioConfig;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.openai.portal.config.PathManager;
import com.yc.cloud.openai.portal.dao.SpeechToTextClient;
import com.yc.cloud.openai.portal.dao.TextToSpeechClient;
import com.yc.cloud.openai.portal.dto.request.SpeechToTextRequest;
import com.yc.cloud.openai.portal.dto.request.TextToSpeechRequest;
import com.yc.cloud.openai.portal.dto.response.SpeechToTextResponse;
import com.yc.cloud.openai.portal.dto.response.TextToSpeechResponse;
import com.yc.cloud.openai.portal.enums.SpeechSpeaker;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.stereotype.Component;

import java.nio.file.Paths;

/**
 * Azure客户端实现类
 */
@Component("AZURE")
@Slf4j
public class AzureClientImpl implements SpeechToTextClient, TextToSpeechClient {

    private final PathManager pathManager;

    public AzureClientImpl(PathManager pathManager) {
        this.pathManager = pathManager;
    }

    @Override
    public SpeechToTextResponse convertSpeechToText(SpeechToTextRequest request) {
        return new SpeechToTextResponse();
    }

    @Override
    public TextToSpeechResponse convertTextToSpeech(TextToSpeechRequest request) {
        //
        String subscriptionKey = "ddd47bd6daa54747883a6d97e28c56f4";
        String subscriptionRegion = "eastus";
        SpeechConfig config = SpeechConfig.fromSubscription(subscriptionKey, subscriptionRegion);
        //设置语音合成发音人
        if (SpeechSpeaker.WOMAN.getValue().equals(request.getSpeaker().getValue())) {
            config.setSpeechSynthesisVoiceName("zh-CN-XiaoxiaoMultilingualNeural");
        } else {
            config.setSpeechSynthesisVoiceName("zh-CN-YunjianNeural");
        }
        val ttsFileName = System.currentTimeMillis() + ".wav";
        val dstPath = Paths.get(pathManager.getTTSFolder(), ttsFileName).toString();
        // 设置音频输出为文件
        AudioConfig audioConfig = AudioConfig.fromWavFileOutput(dstPath); // 将音频
        val text = request.getText();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(config, audioConfig);
        {
            SpeechSynthesisResult result;
            try {
                result = synthesizer.SpeakTextAsync(text).get();
                val textToSpeechResponse = convertTextToSpeechResult(request, result);
                result.close();
                synthesizer.close();
                return textToSpeechResponse;
            } catch (Exception e) {
                Asserts.fail(e.getMessage());
            }
        }
        return new TextToSpeechResponse();
    }

    private TextToSpeechResponse convertTextToSpeechResult(TextToSpeechRequest request, SpeechSynthesisResult result) {
        val textToSpeechResponse = new TextToSpeechResponse();
        if (result.getReason() == ResultReason.SynthesizingAudioCompleted) {
            //调用成功
            val audioData = result.getAudioData();
            val base64AudioData = Base64.encode(audioData);
            textToSpeechResponse.setAudioData(base64AudioData);
            textToSpeechResponse.setText(request.getText());
        } else if (result.getReason() == ResultReason.Canceled) {
            SpeechSynthesisCancellationDetails cancellation = SpeechSynthesisCancellationDetails.fromResult(result);
            String errorMessage;
            if (cancellation.getReason() == CancellationReason.Error) {
                errorMessage = "语音合成失败：" + cancellation.getErrorCode() + " - " + cancellation.getErrorDetails();
                Asserts.fail(errorMessage);
            } else {
                errorMessage = "语音合成失败：" + cancellation.getReason();
            }
            log.error(errorMessage);
            Asserts.fail(errorMessage);
        }
        return textToSpeechResponse;
    }
}
